#ifndef _FLASH_BOARD_H_
#define _FLASH_BOARD_H_

#include <stdio.h>
#include <config.h>
#include <stdbool.h>

// 最大写入失败次数
#define FLASH_MAX_REWRITE_NUMBER                             (5ul)
// 一扇区容量
#define FLASH_MAX_SECTOR_SIZE                                (4096ul)
// 数据读取最大长度
#define FLASH_MAX_OPERATION_LENGTH                           (448 * 1024)

// 内存操作起始地址
#define FLASH_START_WRITE_ADDRESS                            (0ul)

/* 固件地址划分 */
// 引导程序占用扇区数量 - 32Kbytes
#define BOOTLOADER_SECTOR_SIZE                               (8ul)
// 引导程序占用空间大小
#define BOOTLOADER_ACTUAL_OCCUPIED_SPACE                     (BOOTLOADER_SECTOR_SIZE * FLASH_MAX_SECTOR_SIZE)
// 引导程序分区起始地址
#define BOOTLOADER_START_SECTOR_APDR                         FLASH_START_WRITE_ADDRESS
// 引导程序分区结束地址
#define BOOTLOADER_END_SECTOR_APDR                           (BOOTLOADER_START_SECTOR_APDR + BOOTLOADER_ACTUAL_OCCUPIED_SPACE)
// 跳转到引导程序
#define JUMP_BOOTLOADER_APPLICATION                          ((void (*)(void))((uint32_t *)BOOTLOADER_START_SECTOR_APDR))

// 应用程序占用扇区数量 - 220Kbytes
#define APPLICATION_SECTOR_SIZE                              (55ul)
// 应用程序占用空间大小
#define APPLICATION_ACTUAL_OCCUPIED_SPACE                    (APPLICATION_SECTOR_SIZE * FLASH_MAX_SECTOR_SIZE)
// 应用程序分区起始地址
#define APPLICATION_START_SECTOR_ADDR                        BOOTLOADER_END_SECTOR_APDR
// 应用程序分区结束地址
#define APPLICATION_END_SECTOR_ADDR                          (APPLICATION_START_SECTOR_ADDR + APPLICATION_ACTUAL_OCCUPIED_SPACE)
// 跳转应用程序方法
#define JUMP_FIRMWARE_APPLICATION                            ((void (*)(void))((uint32_t *)APPLICATION_START_SECTOR_ADDR))

/* 内部存储器分割分配说明 */
// 设备参数缓存区域 - 4Kbytes
#define FLASH_SECTOR_USE_BY_DEVICE_CACHE                     (1ul)
// 设备参数占用空间
#define FLASE_DEVICE_ACTUAL_OCCUPIED_SPACE                   (FLASH_SECTOR_USE_BY_DEVICE_CACHE * FLASH_MAX_SECTOR_SIZE)
// 设备参数分区起始地址
#define FLASH_START_ADDR_DEVICE_SECTOR                       APPLICATION_END_SECTOR_ADDR
// 设备参数分区结束地址
#define FLASH_END_ADDR_DEVICE_SECTOR                         (FLASH_START_ADDR_DEVICE_SECTOR + FLASE_DEVICE_ACTUAL_OCCUPIED_SPACE)

// // 持卡人信息缓存区域 - 32Kbytes
// #define FLASH_SECTOR_USE_BY_CARDHOLDER_CACHE                 (8ul)
// // 持卡人占用空间
// #define FLASH_CARDHOLDER_ACTUAL_OCCUPIED_SPACE               (FLASH_SECTOR_USE_BY_CARDHOLDER_CACHE * FLASH_MAX_SECTOR_SIZE)
// // 持卡人分区起始地址
// #define FLASH_START_ADDR_CARDHOLDER_SECTOR                   FLASH_END_ADDR_DEVICE_SECTOR
// // 持卡人分区结束地址
// #define FLASH_END_ADDR_CARDHOLDER_SECTOR                     (FLASH_START_ADDR_CARDHOLDER_SECTOR + FLASH_CARDHOLDER_ACTUAL_OCCUPIED_SPACE)

// // 日志信息缓存区域 - 20Kbytes
// #define FLASH_SECTOR_USE_BY_LOG_CACHE                        (5ul)
// // 日志占用空间
// #define FLASH_LOG_ACTUAL_OCCUPIED_SPACE                      (FLASH_SECTOR_USE_BY_LOG_CACHE * FLASH_MAX_SECTOR_SIZE)
// // 日志分区起始地址
// #define FLASH_START_ADDR_LOG_SECTOR                          FLASH_END_ADDR_CARDHOLDER_SECTOR
// // 日志分区结束地址
// #define FLASH_END_ADDR_LOG_SECTOR                            (FLASH_START_ADDR_LOG_SECTOR + FLASH_LOG_ACTUAL_OCCUPIED_SPACE)

// // 临时注册信息缓存区域 - 8KBytes
// #define FLASH_SECTOR_TEMPORARY_FILE_CACHE                    (2ul)
// // 临时注册信息占用空间
// #define FLASH_TEMPORARY_FILE_ACTUAL_OCCUPIED_SPACE           (FLASH_SECTOR_TEMPORARY_FILE_CACHE * FLASH_MAX_SECTOR_SIZE)
// // 临时注册信息分区起始地址
// #define FLASH_START_ADDR_TEMPORARY_FILE_SECTOR               FLASH_END_ADDR_LOG_SECTOR
// // 临时注册信息结束地址
// #define FLASH_END_ADDR_TEMPORARY_FILE_SECTOR                 (FLASH_START_ADDR_TEMPORARY_FILE_SECTOR + FLASH_TEMPORARY_FILE_ACTUAL_OCCUPIED_SPACE)

/**
 * @brief 扇区擦除
 *
 * @param EraseStartAddr - 擦除的扇区
 * @param EraseSize      - 擦除的长度
 */
extern void FlashEraseBlock(uint32_t EraseStartAddr, uint32_t EraseSize);

/**
 * @brief 读取缓存的数据
 *
 * @param ReadStartAddr - 读取起始地址
 * @param pDataOut      - 指向保存数据地址的指针变量
 * @param SizeOut       - 读取数据长度
 */
extern void FlashReadCacheData(uint32_t ReadStartAddr, void *pDataOut, uint32_t SizeOut);

/**
 * @brief 写入一定长度的数据并验证是否成功
 *
 * @param WriteStartAddr - 写入起始地址
 * @param pDataIn        - 指向写入数据地址的指针变量
 * @param SizeIn         - 写入数据长度
 * @return bool          - 写入状态（true：成功 false：失败）
 */
extern bool FlashWriteCacheDataToCheak(uint32_t WriteStartAddr, const void *pDataIn, uint32_t SizeIn);

#endif
